/*
 * @Description: request请求
 * @Author: xinqiao lxq1990.0716@qq.com
 * @Date: 2023-03-27
 * @LastEditors: xinqiao lxq1990.0716@qq.com
 * @LastEditTime: 2025-04-25
 */

import { message } from 'ant-design-vue'
import axios, { AxiosError, AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios'

import { HttpCodeEnum } from '/@/enums/httpEnum'
import { getToken } from '/@/storage'

const MESSAGE_KEY = 'socketMessageKey'

type AxiosConfig = AxiosResponse['config']
type ResponseType = Omit<AxiosResponse, 'config'> & {
  config: AxiosConfig
}

const httpConfig = {
  baseURL: import.meta.env.VITE_BASE_API_PATH,
  timeout: 10000,
  withCredentials: true,
  headers: {
    'Content-Type': 'application/json',
  },
}

class RequestHttp {
  instance: AxiosInstance
  config: IRequestConfig

  public constructor(axiosConfig: AxiosRequestConfig) {
    this.instance = axios.create(axiosConfig)
    this.config = {
      errTip: true,
    }

    // 请求拦截器
    this.instance.interceptors.request.use(
      (req: AxiosConfig) => {
        const token = getToken()
        /** 后台登录跳转-从本地storage获取token */
        if (token) {
          req.headers['Authorization'] = token
        }
        const platformCode = import.meta.env.VITE_GLOB_PLATFORMCODE
        if (['post', 'put'].includes(req.method || '')) {
          req.data['platformCode'] = platformCode
        } else if (['get', 'delete'].includes(req.method || '')) {
          req.params['platformCode'] = platformCode
        }
        return req
      },
      (error: AxiosError) => {
        return Promise.reject(error)
      },
    )

    // 响应拦截器
    this.instance.interceptors.response.use(
      (res: ResponseType) => {
        const { data, config } = res
        if (config?.responseType === 'text') {
          return Promise.resolve({ responseCode: 100000000, responseData: data })
        }
        if (data.code === 0) {
          return Promise.resolve({ responseCode: 100000000, responseData: data })
        }
        const { responseCode, responseMessage } = data
        if (responseCode === HttpCodeEnum.SUCCESS) {
          return Promise.resolve(data)
        }
        if (this.config.errTip) message.error({ content: responseMessage, key: MESSAGE_KEY })
        return Promise.resolve(data)
      },
      (error) => {
        if (error.code === 'ECONNABORTED') {
          message.error({ content: '连接超时，请重试', key: MESSAGE_KEY })
          return Promise.reject(error)
        }
        const { responseMessage, error: errText } = error.response.data
        message.error({ content: responseMessage || errText || error, key: MESSAGE_KEY })
        const errMsg = error?.response?.data?.msg || error?.response?.data?.message || '未知错误，请重试'
        if (!error.config || error.config.isErr) {
          message.destroy()
        }
        error.message = errMsg
        return Promise.reject(error)
      },
    )
  }

  async get<T>(url: string, params: object = {}, config?: IRequestConfig): Promise<T> {
    this.config = { ...this.config, ...config }
    return await this.instance.get(url, { params })
  }

  async post<T, D = any>(url: string, data: D, config?: IRequestConfig): Promise<T> {
    this.config = { ...this.config, ...config }
    return await this.instance.post(url, data)
  }
}

export default new RequestHttp(httpConfig)
